'use strict';

const got = require('got');
const qs = require('qs');
const io = require('socket.io-client');
const { get } = require('lodash');
const HttpsProxyAgent = require('https-proxy-agent');
const { getConfig } = require('./utils');
const { logger } = require('./misc/logger');

let socket = null;

exports.connect = () => {
	const config = getConfig();
	const proxy = get(config, 'proxy');
	const server = get(config, 'server');
	const hotelId = get(config, 'id');
	const port = get(config, 'port');

	let options = {};
	if (proxy) {
		let agent = new HttpsProxyAgent(proxy);
		
		options = {
			secure: true,
			rejectUnauthorized: false,
			reconnect: true,
			agent: agent
		};
	}

	socket = io(`${server}`, {
		transports: ['websocket', 'polling'],
		reconnectionDelay: 10000, // 每间隔10秒重连一次.
		query: {
			hotelId
		},
		...options
	});
	
	socket.on('connect', () => {
		if (socket.connected) {
			logger.log(`Connected to Server!`);
		} else {
			logger.log(`Connect to Server error :(`);
		}
	});
	
	socket.on('disconnect', (reason) => {
		logger.log(`Disconnect from Server :( Reason is: ${reason}`);
	});
	
	socket.on('res', msg => {
		logger.log(`Response from server: ${msg}`);
	});
	
	socket.on('message', (message) => {
		logger.log(`Message from Server: ${message}`);
	});
	
	socket.on('connect_error', (error) => {
		if (process.env.NODE_DEBUG) {
			logger.error('connect_error: ', error);
		} else {
			logger.error('connect_error: ', get(error, 'description.message'));
		}
	});
	
	socket.on('connect_timeout', (timeout) => {
		logger.error('connect_timeout: ', timeout);
	});
	
	socket.on('error', (error) => {
		if (process.env.NODE_DEBUG) {
			logger.error('socket_error: ', error);
		} else {
			logger.error('socket_error: ', get(error, 'description.message'));
		}
	});
	
	socket.on('reconnect_error', (error) => {
		if (process.env.NODE_DEBUG) {
			logger.error('reconnect_error: ', error);
		} else {
			logger.error('reconnect_error: ', get(error, 'description.message'));
		}
	});
	
	socket.on('reconnect_failed', () => {
		logger.error(`reconnect_failed :(`);
	});
	
	socket.on('call', async function (query, fn) {
		if (process.env.NODE_DEBUG) {
			logger.log('socket - call query----', query);
		}
		
		const { api, method } = query;
		logger.log(`api: ${api}`);
		
		let data;
		try {
			console.log(`http://localhost:${port}/${api}`)
			const res = await got[method || 'get'](`http://localhost:${port}/${api}`, {
				...(method === 'post' ? { json: query } : { searchParams: qs.stringify(query) }),
				responseType: 'json'
			})
			
			data = res.body;
			
			if (process.env.NODE_DEBUG) {
				logger.log('response', data);
			}
		} catch (err) {
			logger.error('http response: ', err);
			data = {
				errCode: 1,
				errMsg: err.message,
			}
		}
		
		fn(data);
	});
}

exports.socket = socket;

exports.getSocket = function() {
	return socket;
}
